!-------------------------------------------------------------LICENSE--------------------------------------------------------------!
!                                                                                                                                  !
!The MAP code is written in Fortran language for magnetohydrodynamics (MHD) calculation with the adaptive mesh refinement (AMR)    !
!and Message Passing Interface (MPI) parallelization.                                                                              !
!                                                                                                                                  !
!Copyright (C) 2012                                                                                                                !
!Ronglin Jiang                                                                                                                     !
!rljiang@ssc.net.cn                                                                                                                !
!585 Guoshoujing Road. Pudong, Shanghai, P.R.C. 201203                                                                             !
!                                                                                                                                  !
!This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License         !
!as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.             !
!                                                                                                                                  !
!This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of    !
!MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.                        !
!                                                                                                                                  !
!You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software     !
!Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.                                                   !
!                                                                                                                                  !
!-------------------------------------------------------------LICENSE--------------------------------------------------------------!

!----------------------------------------------------------------------------------------------------------------------------------|
module interface_amr
   interface
      subroutine amr(base)
         use parameters
         use block_define
         implicit none
         type(block), pointer, intent(in) :: base
      end subroutine amr
   end interface
end module interface_amr

!----------------------------------------------------------------------------------------------------------------------------------|

module interface_block_boundary_physi
   interface
      subroutine block_boundary_physi (current, dir, sides, pos,                                                                   &
         ro_flag, mx_flag, my_flag, mz_flag, bx_flag, by_flag, bz_flag, en_flag, po_flag, lv)
         use parameters
         use block_define
         implicit none
         character(1), intent(in) :: dir, sides, pos
         integer(4), optional, intent(in) :: lv
         logical(4), intent(in) :: ro_flag, mx_flag, my_flag, mz_flag, bx_flag, by_flag, bz_flag, en_flag, po_flag
         type(block), pointer, intent(in) :: current
      end subroutine block_boundary_physi
   end interface
end module interface_block_boundary_physi

!----------------------------------------------------------------------------------------------------------------------------------|

module interface_block_boundary_potential
   interface
      subroutine block_boundary_potential (current)
         use parameters
         use block_define
         implicit none
         type(block), pointer, intent(inout) :: current
      end subroutine block_boundary_potential
   end interface
end module interface_block_boundary_potential

!----------------------------------------------------------------------------------------------------------------------------------|

module interface_block_destroy
   interface
      recursive subroutine block_destroy (current, n_destroy_blocks)
         use parameters
         use block_define
         implicit none
         integer(4), intent(in) :: n_destroy_blocks
         type(block), pointer, intent(in) :: current
      end subroutine block_destroy
   end interface
end module interface_block_destroy

!----------------------------------------------------------------------------------------------------------------------------------|

module interface_block_exchange
   interface
      subroutine block_exchange (current, dir, ro_flag, mx_flag, my_flag, mz_flag, bx_flag, by_flag, bz_flag, en_flag,             &
         az_flag, po_flag, fix_flag)
         use parameters
         use block_define
         implicit none
         character(1), intent(in) :: dir
         logical(4), optional :: ro_flag, mx_flag, my_flag, mz_flag, bx_flag, by_flag, bz_flag, en_flag, az_flag, po_flag, fix_flag
         type(block), pointer, intent(in) :: current
      end subroutine block_exchange
   end interface
end module interface_block_exchange

!----------------------------------------------------------------------------------------------------------------------------------|

module interface_block_generate
   interface
      recursive subroutine block_generate (current, var_regrid_flag)
         use parameters
         use block_define
         implicit none
         integer(4), intent(in) :: var_regrid_flag
         type(block), pointer, intent(in) :: current
      end subroutine block_generate
   end interface
end module interface_block_generate

!----------------------------------------------------------------------------------------------------------------------------------|

module interface_block_output
   interface
      subroutine block_output (current)
         use parameters
         use block_define
         implicit none
         type(block), pointer, intent(in) :: current
      end subroutine block_output
   end interface
end module interface_block_output

!----------------------------------------------------------------------------------------------------------------------------------|

module interface_block_reflux
   interface
      subroutine block_reflux (current)
         use parameters
         use block_define
         implicit none
         type(block), pointer, intent(in) :: current
      end subroutine block_reflux
   end interface
end module interface_block_reflux

!----------------------------------------------------------------------------------------------------------------------------------|

module interface_block_shareblock
   interface
      subroutine block_shareblock (current, ro_flag, mx_flag, my_flag, mz_flag, bx_flag, by_flag, bz_flag, en_flag,                &
         az_flag, po_flag)
         use parameters
         use block_define
         implicit none
         logical(4), optional :: ro_flag, mx_flag, my_flag, mz_flag, bx_flag, by_flag, bz_flag, en_flag, az_flag, po_flag
         type(block), pointer, intent(inout) :: current
      end subroutine block_shareblock
   end interface
end module interface_block_shareblock

!----------------------------------------------------------------------------------------------------------------------------------|

module interface_block_update
   interface
      subroutine block_update (base, n_var, ro_flag, mx_flag, my_flag, mz_flag, bx_flag, by_flag, bz_flag, en_flag,                &
         az_flag, po_flag)
         use parameters
         use block_define
         implicit none
         integer(4), intent(in) :: n_var
         logical(4), optional :: ro_flag, mx_flag, my_flag, mz_flag, bx_flag, by_flag, bz_flag, en_flag, az_flag, po_flag
         type(block), pointer, intent(in) :: base
      end subroutine block_update
   end interface
end module interface_block_update

!----------------------------------------------------------------------------------------------------------------------------------|

module interface_check_state
   interface
      subroutine check_state (ro, mx, my, mz, bx, by, bz, en, x, y, nx, ny, gm, ab_density, ab_pressure, max_te_ro, max_speed)
         implicit none
         integer(4), intent(in) :: nx, ny
         integer(4), intent(inout), optional :: ab_density, ab_pressure
         real(8) :: gm
         real(8), dimension(nx) :: x
         real(8), dimension(ny) :: y
         real(8), intent(inout), optional :: max_te_ro, max_speed
         real(8), dimension(nx, ny), intent(inout) :: ro, mx, my, mz, bx, by, bz, en
      end subroutine check_state
   end interface
end module interface_check_state

!----------------------------------------------------------------------------------------------------------------------------------|

module interface_framework_sync
   interface
      subroutine framework_sync (base)
         use parameters
         use block_define
         implicit none
         type(block), pointer, intent(in) :: base
      end subroutine framework_sync
   end interface
end module interface_framework_sync

!----------------------------------------------------------------------------------------------------------------------------------|

module interface_hilbert_space_filling_2d
   interface
      recursive subroutine hilbert_space_filling_2d (base, current, start_pos, end_pos, start_point, order, var_regrid_flag)
         use parameters
         use block_define
         implicit none
         integer(4), intent(in) :: order, var_regrid_flag
         integer(4), dimension(2), intent(in) :: start_pos, end_pos, start_point
         type(block), pointer, intent(in) :: base
         type(block), pointer, intent(in) :: current
      end subroutine hilbert_space_filling_2d
   end interface
end module interface_hilbert_space_filling_2d

!----------------------------------------------------------------------------------------------------------------------------------|

module interface_integrate
   interface
      subroutine integrate (current)
         use parameters
         use block_define
         implicit none
         type(block), pointer, intent(in) :: current
      end subroutine integrate
   end interface
end module interface_integrate

!----------------------------------------------------------------------------------------------------------------------------------|

module interface_integrate_sub
   interface
      subroutine integrate_sub (current)
         use parameters
         use block_define
         implicit none
         type(block), pointer, intent(in) :: current
      end subroutine integrate_sub
   end interface
end module interface_integrate_sub

!----------------------------------------------------------------------------------------------------------------------------------|

module interface_load_balance
   interface
      subroutine load_balance (base)
         use parameters
         use block_define
         implicit none
         type(block), pointer, intent(in) :: base
      end subroutine load_balance
   end interface
end module interface_load_balance

!----------------------------------------------------------------------------------------------------------------------------------|
module interface_load_state
   interface
      subroutine load_state (base)
         use parameters
         use block_define
         implicit none
         type(block), pointer, intent(in) :: base
      end subroutine load_state
   end interface
end module interface_load_state

!----------------------------------------------------------------------------------------------------------------------------------|

module interface_model_initial
   interface
      subroutine model_initial (base)
         use parameters
         use block_define
         implicit none
         type(block), pointer, intent(inout) :: base
      end subroutine model_initial
   end interface
end module interface_model_initial

!----------------------------------------------------------------------------------------------------------------------------------|

module interface_neigh_exchange
   interface
      subroutine neigh_exchange(current, buffer_send_x, buffer_send_y, buffer_recv_x, buffer_recv_y,                               &
            dir, n_var, ro_flag, mx_flag, my_flag, mz_flag, bx_flag, by_flag, bz_flag, en_flag, az_flag, po_flag, fix_flag)
         use parameters
         use block_define
         implicit none
         character(1), intent(in) :: dir
         integer(4), intent(in) :: n_var
         logical(4), optional :: ro_flag, mx_flag, my_flag, mz_flag, bx_flag, by_flag, bz_flag, en_flag, az_flag, po_flag, fix_flag
         real(8), intent(inout) :: buffer_send_x(n_var, ng, ny_no_bnd, exchange_size_send_x)
         real(8), intent(inout) :: buffer_send_y(n_var, nx_block, ng, exchange_size_send_y)
         real(8), intent(inout) :: buffer_recv_x(n_var, ng, ny_no_bnd, exchange_size_recv_x)
         real(8), intent(inout) :: buffer_recv_y(n_var, nx_block, ng, exchange_size_recv_y)
         type(block), pointer, intent(in) :: current
      end subroutine neigh_exchange
   end interface
end module interface_neigh_exchange

!----------------------------------------------------------------------------------------------------------------------------------|

module interface_neigh_reflux
   interface
      subroutine neigh_reflux(base)
         use parameters
         use block_define
         implicit none
         type(block), pointer, intent(in) :: base
      end subroutine neigh_reflux
   end interface
end module interface_neigh_reflux

!----------------------------------------------------------------------------------------------------------------------------------|

module interface_neigh_shareblock
   interface
      subroutine neigh_shareblock(base, buffer_send_x, buffer_send_y, buffer_recv_x, buffer_recv_y,                                &
            n_var, ro_flag, mx_flag, my_flag, mz_flag, bx_flag, by_flag, bz_flag, en_flag, az_flag, po_flag)
         use parameters
         use block_define
         implicit none
         integer(4), intent(in) :: n_var
         logical(4), optional :: ro_flag, mx_flag, my_flag, mz_flag, bx_flag, by_flag, bz_flag, en_flag, az_flag, po_flag
         real(8), intent(inout) :: buffer_send_x(n_var, ng + 1, ny_block, shareblock_size_send_x)
         real(8), intent(inout) :: buffer_send_y(n_var, nx_block, ng + 1, shareblock_size_send_y)
         real(8), intent(inout) :: buffer_recv_x(n_var, ng + 1, ny_block, shareblock_size_recv_x)
         real(8), intent(inout) :: buffer_recv_y(n_var, nx_block, ng + 1, shareblock_size_recv_y)
         type(block), pointer, intent(in) :: base
      end subroutine neigh_shareblock
   end interface
end module interface_neigh_shareblock

!----------------------------------------------------------------------------------------------------------------------------------|

module interface_neigh_statistics
   interface
      subroutine neigh_statistics(base)
         use parameters
         use block_define
         implicit none
         type(block), pointer, intent(in) :: base
      end subroutine neigh_statistics
   end interface
end module interface_neigh_statistics

!----------------------------------------------------------------------------------------------------------------------------------|

module interface_regrid
   interface
      subroutine regrid(current)
         use parameters
         use block_define
         implicit none
         type(block), pointer, intent(in) :: current
      end subroutine regrid
   end interface
end module interface_regrid

!----------------------------------------------------------------------------------------------------------------------------------|
module interface_save_state
   interface
      subroutine save_state(base)
         use parameters
         use block_define
         implicit none
         type(block), pointer, intent(in) :: base
      end subroutine save_state
   end interface
end module interface_save_state

!----------------------------------------------------------------------------------------------------------------------------------|

!module interface_tvd_mmc_x
!   interface
!      subroutine tvd_mmc_x(ro, mx, my, mz, bx, by, bz, en, gx,                                                                    &
!         nx, ny, ng, n_neighs, dx, dt, max_speed, gm, div_clean_flag,                                                              &
!         fxro_bnd, fxmx_bnd, fxmy_bnd, fxmz_bnd, fxbx_bnd, fxby_bnd, fxbz_bnd, fxen_bnd)
!         implicit none
!         integer(4), intent(in) :: nx, ny, ng, n_neighs, div_clean_flag
!         real(8), intent(in) :: dx, dt, gm, max_speed
!         real(8), dimension(nx, ny), intent(inout) :: ro, mx, my, mz, bx, by, bz, en, gx
!         real(8), dimension(ny, n_neighs), optional, intent(inout) ::                                                              &
!            fxro_bnd, fxmx_bnd, fxmy_bnd, fxmz_bnd, fxbx_bnd, fxby_bnd, fxbz_bnd, fxen_bnd
!      end subroutine tvd_mmc_x
!   end interface
!end module interface_tvd_mmc_x

!!----------------------------------------------------------------------------------------------------------------------------------|

!module interface_tvd_mmc_y
!   interface
!      subroutine tvd_mmc_y(ro, mx, my, mz, bx, by, bz, en, gy,                                                                    &
!         nx, ny, ng, n_neighs, dy, dt, max_speed, gm, div_clean_flag,                                                              &
!         fyro_bnd, fymx_bnd, fymy_bnd, fymz_bnd, fybx_bnd, fyby_bnd, fybz_bnd, fyen_bnd)
!         implicit none
!         integer(4), intent(in) :: nx, ny, ng, n_neighs, div_clean_flag
!         real(8), intent(in) :: dy, dt, gm, max_speed
!         real(8), dimension(nx, ny), intent(inout) :: ro, mx, my, mz, bx, by, bz, en, gy
!         real(8), dimension(nx, n_neighs), optional, intent(inout) ::                                                              &
!            fyro_bnd, fymx_bnd, fymy_bnd, fymz_bnd, fybx_bnd, fyby_bnd, fybz_bnd, fyen_bnd
!      end subroutine tvd_mmc_y
!   end interface
!end module interface_tvd_mmc_y

!!----------------------------------------------------------------------------------------------------------------------------------|

!module interface_tvd_lf_x
!   interface
!      subroutine tvd_lf_x(ro, mx, my, mz, bx, by, bz, en, gx,                                                                     &
!         nx, ny, ng, n_neighs, dx, dt, gm, div_clean_flag,                                                                         &
!         fxro_bnd, fxmx_bnd, fxmy_bnd, fxmz_bnd, fxbx_bnd, fxby_bnd, fxbz_bnd, fxen_bnd, riemann_solver_flag)
!         implicit none
!         integer(4), intent(in) :: nx, ny, ng, n_neighs, riemann_solver_flag, div_clean_flag
!         real(8), intent(in) :: dx, dt, gm
!         real(8), dimension(nx, ny), intent(inout) :: ro, mx, my, mz, bx, by, bz, en, gx
!         real(8), dimension(ny, n_neighs), optional, intent(inout) ::                                                              &
!            fxro_bnd, fxmx_bnd, fxmy_bnd, fxmz_bnd, fxbx_bnd, fxby_bnd, fxbz_bnd, fxen_bnd
!      end subroutine tvd_lf_x
!   end interface
!end module interface_tvd_lf_x

!!----------------------------------------------------------------------------------------------------------------------------------|

!module interface_tvd_lf_y
!   interface
!      subroutine tvd_lf_y(ro, mx, my, mz, bx, by, bz, en, gy,                                                                     &
!         nx, ny, ng, n_neighs, dy, dt, gm, div_clean_flag,                                                                         &
!         fyro_bnd, fymx_bnd, fymy_bnd, fymz_bnd, fybx_bnd, fyby_bnd, fybz_bnd, fyen_bnd, riemann_solver_flag)
!         implicit none
!         integer(4), intent(in) :: nx, ny, ng, n_neighs, riemann_solver_flag, div_clean_flag
!         real(8), intent(in) :: dy, dt, gm
!         real(8), dimension(nx, ny), intent(inout) :: ro, mx, my, mz, bx, by, bz, en, gy
!         real(8), dimension(nx, n_neighs), optional, intent(inout) ::                                                              &
!            fyro_bnd, fymx_bnd, fymy_bnd, fymz_bnd, fybx_bnd, fyby_bnd, fybz_bnd, fyen_bnd
!      end subroutine tvd_lf_y
!   end interface
!end module interface_tvd_lf_y

!!----------------------------------------------------------------------------------------------------------------------------------|

!module interface_weno
!   interface
!      subroutine weno(ro, mx, my, mz, bx, by, bz, en, gx, gy,                                                                     &
!         nx, ny, ng, n_neighs, dx, dy, dt, gm, div_clean_flag,                                                                     &
!         fxro_bnd, fxmx_bnd, fxmy_bnd, fxmz_bnd, fxbx_bnd, fxby_bnd, fxbz_bnd, fxen_bnd,                                           &
!         fyro_bnd, fymx_bnd, fymy_bnd, fymz_bnd, fybx_bnd, fyby_bnd, fybz_bnd, fyen_bnd, riemann_solver_flag)
!         implicit none
!         integer(4), intent(in) :: nx, ny, ng, n_neighs, riemann_solver_flag, div_clean_flag
!         real(8), intent(in) :: dx, dy, dt, gm
!         real(8), dimension(nx, ny), intent(inout) :: ro, mx, my, mz, bx, by, bz, en, gx, gy
!         real(8), dimension(ny, n_neighs), optional, intent(inout) ::                                                              &
!            fxro_bnd, fxmx_bnd, fxmy_bnd, fxmz_bnd, fxbx_bnd, fxby_bnd, fxbz_bnd, fxen_bnd
!         real(8), dimension(nx, n_neighs), optional, intent(inout) ::                                                              &
!            fyro_bnd, fymx_bnd, fymy_bnd, fymz_bnd, fybx_bnd, fyby_bnd, fybz_bnd, fyen_bnd
!      end subroutine weno
!   end interface
!end module interface_weno

!!----------------------------------------------------------------------------------------------------------------------------------|

!module interface_ucs
!   interface
!      subroutine ucs(ro, mx, my, mz, bx, by, bz, en, gx, gy,                                                                      &
!         nx, ny, ng, n_neighs, dx, dy, dt, gm,                                                                                     &
!         fxro_bnd, fxmx_bnd, fxmy_bnd, fxmz_bnd, fxbx_bnd, fxby_bnd, fxbz_bnd, fxen_bnd,                                           &
!         fyro_bnd, fymx_bnd, fymy_bnd, fymz_bnd, fybx_bnd, fyby_bnd, fybz_bnd, fyen_bnd)
!         implicit none
!         integer(4), intent(in) :: nx, ny, ng, n_neighs
!         real(8), intent(in) :: dx, dy, dt, gm
!         real(8), dimension(nx, ny), intent(inout) :: ro, mx, my, mz, bx, by, bz, en, gx, gy
!         real(8), dimension(ny, n_neighs), optional, intent(inout) ::                                                              &
!            fxro_bnd, fxmx_bnd, fxmy_bnd, fxmz_bnd, fxbx_bnd, fxby_bnd, fxbz_bnd, fxen_bnd
!         real(8), dimension(nx, n_neighs), optional, intent(inout) ::                                                              &
!            fyro_bnd, fymx_bnd, fymy_bnd, fymz_bnd, fybx_bnd, fyby_bnd, fybz_bnd, fyen_bnd
!      end subroutine ucs
!   end interface
!end module interface_ucs

!----------------------------------------------------------------------------------------------------------------------------------|

